package org.myontology.init;

import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Enumeration;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.hibernate.classic.Session;
import org.hsqldb.Server;
import org.myontology.controller.WebAttributeHolder;
import org.myontology.db.HibernateSessionProvider;

import view.HTMLUIcomponents.AbstractComponent;
import controller.sesameDataConnector.AbstractDataConnector;

public class Initializer extends HttpServlet {

	private static Logger logger = Logger.getLogger(Initializer.class);
	private static String dbPath;
	private static Server server;
	
	@Override
	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		ServletContext context = getServletContext();
		String realPath = context.getRealPath("/");
	    String fileSep = System.getProperty("file.separator");

	    if (realPath != null && (!realPath.endsWith(fileSep)))
	      realPath = realPath + fileSep;
	    realPath = realPath + "WEB-INF/log4j.properties";
	    logger.debug(realPath);

	    //load the configuration for this application's loggers using the
	    // log4j.properties file
	    PropertyConfigurator.configure(realPath);

		logger.info("initialized logging with WEB-INF/log4j.properties");
		
		Enumeration e = config.getServletContext().getInitParameterNames();
		WebAttributeHolder attributes = new WebAttributeHolder(null);
		logger.info("adding application constants");
		while (e.hasMoreElements()) {
			String key = (String)e.nextElement();
			String value = config.getServletContext().getInitParameter(key);
			logger.info("Key: "+key+" - "+value);
			attributes.setApplicationAttribute(key, value);
		}
		
		
		////////////////////////////////////////////
		/////////tmp
		/////////////////////////////////////////
		if( AbstractComponent.isWordNetDirectorySet()==false ) {
			AbstractComponent.setWordNetDirectory( context.getInitParameter("WordNetDirectory") );
		}
	
		String tmp = context.getInitParameter( "SesameDataDirectoryApplication" );
		if( tmp==null || tmp.equals("")) {
			tmp = context.getInitParameter( "DevelopmentSesameDataDirectory" );
		}
		AbstractDataConnector.SetSesameDataDirectory( tmp );
		
		if( AbstractComponent.isWordNetDirectorySet()==false ) {
			AbstractComponent.setWordNetDirectory( context.getInitParameter("WordNetDirectory") );
		}
		
		
		
	
		controller.HelperFunctions.setMakeReachableURI( new String[]{ "http://myontology.org/v0/", "" } );
		controller.HelperFunctions.SetContextRoot( context.getContextPath() );
	
		
		

//		controller.ElementRanker.Init();
		
		dbPath = config.getServletContext().getRealPath("/data/");
		startServer();
	}
	/**
	 * @param dbPath
	 */
	private static void startServer() {
		//		final String dbName = "-dbname.0 test";
				if ("1".equals(Globals.internalDb.getValue(new WebAttributeHolder(null)))) {
					logger.info("starting up database hsql at path:");
					logger.info(dbPath);
					server = new Server();
					server.setDatabaseName(0, "test");
					server.setDatabasePath(0, dbPath);
					
					server.start();
				}
				Session s = null;
				try {
					s = (Session)new HibernateSessionProvider().create(null);
					s.beginTransaction();
					Statement stmt = s.connection().createStatement();
					String query = "SELECT LIMIT 0 1 name,type FROM logs";
					ResultSet rs = stmt.executeQuery(query);
				}
				catch (Exception ex) {
					logger.error("Error connecting to the database",ex);
					logger.error("if context-param internalDb is 0, try use 1");
					logger.error("else start hsql external with the database from "+dbPath);
					
				}
				if (s!=null) {
					s.clear();
					s.close();
				}
	}
	@Override
	public void destroy() {
//		try {
//			while (true) {
//				Thread.sleep(500);
//				System.err.println(getServletContext().getServlets().hasMoreElements());
//				
//			}
//		}
//		catch (Exception ee) {}
		logger.info("shutting down");
		
		closeDb();
		logger.info("close dataconnector");
		AbstractDataConnector.close();
	}
	/**
	 * 
	 */
	private static void closeDb() {
		Session s = null;
		try {
			
			
			Thread t = new Thread() {
				@Override
				public void run() {
					try {
						Thread.sleep(2000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					if (server!=null)
						System.exit(1);
				}
			};
			t.start();
			
			s = (Session)new HibernateSessionProvider().create(null);
			s.beginTransaction();
			Statement stmt = s.connection().createStatement();
			String query = "CHECKPOINT";
			stmt.execute(query);
			stmt.execute("SHUTDOWN");
			server = null;
			t.join();
		}
		catch (Exception ex) {
			logger.error("Error connecting to the database",ex);
			
			
		}
//		if (s!=null) {
//			s.clear();
//			s.close();
//		}
//		if (server!=null) {
//			try {
//				Thread t = new Thread() {
//					@Override
//					public void run() {
//						server.signalCloseAllServerConnections();
//						server.shutdown();
//						
//						System.err.println();
//					}
//				};
//				t.setDaemon(true);
//				t.start();
//				Thread.sleep(1000);
//				
////				server.stop();
//			}
//			catch (Exception e) {
//				logger.error("destroy: ",e);
//			}
//		}
	}
}
